
import * as Blockly from 'blockly/core'
import { getAllFormList } from '../utils/component'
import { getContextText } from '../utils/block'
// 1.----------表单校验-------------------------------------------
const json = {
  type: 'form_validate',
  message0: '表单校验 %1 校验成功%2 校验失败%3 ',
  args0: [
    // 动态生成选项
    {
      'type': 'input_dummy',
      'name': 'FORM_INPUT'
    },
    {
      'type': 'input_value',
      'name': 'success_func',
      'check': ['callback_function_expression']
    },
    {
      'type': 'input_value',
      'name': 'error_func',
      'check': ['callback_function_expression']
    }
  ],
  extensions: ['dynamic_form_extension'],
  previousStatement: true,
  nextStatement: true,
  // inputsInline: true,
  style: 'action_blocks',
  tooltip: '',
  helpUrl: ''
  // mutator: 'form_validate_mutator'
}

Blockly.Extensions.register('dynamic_form_extension',
  function () {
    this.getInput('FORM_INPUT')
      .appendField(new Blockly.FieldDropdown(
        function () {
          var options = []
          // 获取页面所有的表单
          const comList = getAllFormList()

          if (!comList.length) {
            options = [['没有数据', 'noData']]
            return options
          }
          for (var i = 0; i < comList.length; i++) {
            const com = comList[i]
            const dateString = `${com.name}（${com.key}）`
            options.push([dateString, com.key])
          }
          return options
        }), 'Form')
  })

// 创建积木
Blockly.Blocks['form_validate'] = {
  init: function () {
    this.jsonInit(json)
  }
}

Blockly.JavaScript['form_validate'] = function (block) {
  const compVar = block.getFieldValue('Form')
  const context = getContextText(block, compVar)
  let code = `${context}.getComponent('${compVar}').validate().then(`

  const onSuccess = Blockly.JavaScript.valueToCode(block, 'success_func',
    Blockly.JavaScript.ORDER_COMMA) || `() => {}`
  code = code + onSuccess + ','
  const onError = Blockly.JavaScript.valueToCode(block, 'error_func',
    Blockly.JavaScript.ORDER_COMMA) || `() => {}`
  code = code + onError + `)`
  return code + '\n'
}

// 2.----------表单 自定义流程处理 handProcessEvent-------------------------------------------

const handProcessJson = {
  type: 'form_handle_process',
  message0: '表单%1 自定义流程处理 参数 流程id %2 服务id %3 流程key %4  处理成功回调%5 处理失败回调%6 ',
  args0: [
    // 动态生成选项
    {
      'type': 'input_dummy',
      'name': 'FORM_INPUT'
    },
    {
      'type': 'input_value',
      name: 'taskId'
    },
    {
      type: 'input_value',
      name: 'serviceKey'
    },
    {
      type: 'input_value',
      name: 'processKey'
    },
    {
      'type': 'input_value',
      'name': 'success_func',
      'check': ['callback_function_expression']
    },
    {
      'type': 'input_value',
      'name': 'error_func',
      'check': ['callback_function_expression']
    }
  ],
  extensions: ['dynamic_form_extension'],
  previousStatement: true,
  nextStatement: true,
  // inputsInline: true,
  style: 'action_blocks',
  tooltip: '',
  helpUrl: ''
  // mutator: 'form_validate_mutator'
}

// 创建积木
Blockly.Blocks['form_handle_process'] = {
  init: function () {
    this.jsonInit(handProcessJson)
  }
}

Blockly.JavaScript['form_handle_process'] = function (block) {
  const compVar = block.getFieldValue('Form')
  const taskId = Blockly.JavaScript.valueToCode(block, 'taskId',
    Blockly.JavaScript.ORDER_COMMA) || '\'\''
  const serviceKey = Blockly.JavaScript.valueToCode(block, 'serviceKey',
    Blockly.JavaScript.ORDER_COMMA) || '\'\''
  const processKey = Blockly.JavaScript.valueToCode(block, 'processKey',
    Blockly.JavaScript.ORDER_COMMA) || '\'\''
  let code = `context.getComponent('${compVar}').handProcessEvent(${taskId}, ${serviceKey}, ${processKey}).then(`

  const onSuccess = Blockly.JavaScript.valueToCode(block, 'success_func',
    Blockly.JavaScript.ORDER_COMMA) || `() => {}`
  code = code + onSuccess + ','
  const onError = Blockly.JavaScript.valueToCode(block, 'error_func',
    Blockly.JavaScript.ORDER_COMMA) || `() => {}`
  code = code + onError + `)`
  return code + '\n'
}

// 3---------表单流程转办------------------------------
const transferProcessJson = {
  type: 'form_transfer_process',
  message0: '表单%1 流程转办 参数 服务id %2  转办用户id%3 转办成功回调%4  转办失败回调%5',
  args0: [
    // 动态生成选项
    {
      'type': 'input_dummy',
      'name': 'FORM_INPUT'
    },
    {
      type: 'input_value',
      name: 'serviceKey'
    },
    {
      type: 'input_value',
      name: 'userId'
    },
    {
      'type': 'input_value',
      'name': 'success_func',
      'check': ['callback_function_expression']
    },
    {
      'type': 'input_value',
      'name': 'error_func',
      'check': ['callback_function_expression']
    }
  ],
  extensions: ['dynamic_form_extension'],
  previousStatement: true,
  nextStatement: true,
  // inputsInline: true,
  style: 'action_blocks',
  tooltip: '',
  helpUrl: ''
  // mutator: 'form_validate_mutator'
}
// 创建积木
Blockly.Blocks['form_transfer_process'] = {
  init: function () {
    this.jsonInit(transferProcessJson)
  }
}

Blockly.JavaScript['form_transfer_process'] = function (block) {
  const compVar = block.getFieldValue('Form')
  const serviceKey = Blockly.JavaScript.valueToCode(block, 'serviceKey',
    Blockly.JavaScript.ORDER_ATOMIC) || '\'\''
  const userId = Blockly.JavaScript.valueToCode(block, 'userId',
    Blockly.JavaScript.ORDER_ATOMIC) || '\'\''
  let code = `context.getComponent('${compVar}').handProcessEvent(${serviceKey}, ${userId}).then(`

  const onSuccess = Blockly.JavaScript.valueToCode(block, 'success_func',
    Blockly.JavaScript.ORDER_ATOMIC) || `() => {}`
  code = code + onSuccess + ','
  const onError = Blockly.JavaScript.valueToCode(block, 'error_func',
    Blockly.JavaScript.ORDER_ATOMIC) || `() => {}`
  code = code + onError + `)`
  return code + '\n'
}

// 4----------------表单提交------------------
const submitJson = {
  type: 'form_submit',
  message0: '提交表单 %1  ',
  args0: [
    // 动态生成选项
    {
      'type': 'input_dummy',
      'name': 'FORM_INPUT'
    }
  ],
  mutator: 'form_submit_mutator',
  extensions: ['dynamic_form_extension'],
  previousStatement: true,
  nextStatement: true,
  // inputsInline: true,
  style: 'action_blocks',
  tooltip: '',
  helpUrl: ''
}

// 创建积木
Blockly.Blocks['form_submit'] = {
  init: function () {
    this.jsonInit(submitJson)
  }
}
Blockly.JavaScript['form_submit'] = function (block) {
  const compVar = block.getFieldValue('Form')
  const context = getContextText(block, compVar)
  let code = `${context}.getComponent('${compVar}').submit().then(`
  if (block.successCount_) {
    const onSuccess = Blockly.JavaScript.valueToCode(block, 'success_func',
      Blockly.JavaScript.ORDER_COMMA) || '(response) => {\n}'
    code = code + onSuccess + ','
  }
  if (block.errorCount_) {
    const onError = Blockly.JavaScript.valueToCode(block, 'error_func',
      Blockly.JavaScript.ORDER_COMMA) || '(error) => {}\n'
    code = code + onError
  }
  code = code + ')'
  return code + '\n'
}

// 5----------------获取表单值------------------
const getValuesJson = {
  type: 'form_get_values',
  message0: '获取表单值 %1  ',
  args0: [
    // 动态生成选项
    {
      'type': 'input_dummy',
      'name': 'FORM_INPUT'
    }
  ],
  extensions: ['dynamic_form_extension'],
  output: 'Object',
  // inputsInline: true,
  style: 'action_blocks',
  tooltip: '',
  helpUrl: ''
}
Blockly.Blocks['form_get_values'] = {
  init: function () {
    this.jsonInit(getValuesJson)
  }
}

Blockly.JavaScript['form_get_values'] = function (block) {
  const compVar = block.getFieldValue('Form')
  const context = getContextText(block, compVar)
  const code = `await ${context}.getComponent('${compVar}').dispatch('getValues')`
  return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]
}

// --------------6重置表单-----------
const resetJson = {
  type: 'form_reset',
  message0: '重置表单 %1  ',
  args0: [
    // 动态生成选项
    {
      'type': 'input_dummy',
      'name': 'FORM_INPUT'
    }
  ],
  extensions: ['dynamic_form_extension'],
  previousStatement: true,
  nextStatement: true,
  // inputsInline: true,
  style: 'action_blocks',
  tooltip: '',
  helpUrl: ''
}
Blockly.Blocks['form_reset'] = {
  init: function () {
    this.jsonInit(resetJson)
  }
}
Blockly.JavaScript['form_reset'] = function (block) {
  const compVar = block.getFieldValue('Form')
  const context = getContextText(block, compVar)
  const code = `${context}.getComponent('${compVar}').dispatch('reset')`
  return code + '\n'
}

// --------------7表单追加值 addValues-----------

const addValuesJson = {
  type: 'form_add_values',
  message0: '表单 %1 添加值为 %2',
  args0: [
    // 动态生成选项
    {
      'type': 'input_dummy',
      'name': 'FORM_INPUT'
    },
    {
      'type': 'input_value',
      'name': 'VALUE_INPUT',
      'check': 'Object'
    }
  ],
  extensions: ['dynamic_form_extension'],
  previousStatement: true,
  nextStatement: true,
  inputsInline: true,
  style: 'action_blocks',
  tooltip: '',
  helpUrl: ''
}
Blockly.Blocks['form_add_values'] = {
  init: function () {
    this.jsonInit(addValuesJson)
  }
}
Blockly.JavaScript['form_add_values'] = function (block) {
  const compVar = block.getFieldValue('Form')
  const context = getContextText(block, compVar)
  const values = Blockly.JavaScript.valueToCode(block, 'VALUE_INPUT',
    Blockly.JavaScript.ORDER_FUNCTION_CALL) || '{}'
  // const code = `${context}.getComponent('${compVar}').addValues(${values})`
  const code = `${context}.getComponent('${compVar}').dispatch('addValues',${values})`
  return code + '\n'
}

// --------------8表单设置值 setValues -----------

const setValuesJson = {
  type: 'form_set_values',
  message0: '设置表单 %1 赋值为 %2',
  args0: [
    // 动态生成选项
    {
      'type': 'input_dummy',
      'name': 'FORM_INPUT'
    },
    {
      'type': 'input_value',
      'name': 'VALUE_INPUT',
      'check': 'Object'
    }
  ],
  extensions: ['dynamic_form_extension'],
  previousStatement: true,
  nextStatement: true,
  inputsInline: true,
  style: 'action_blocks',
  tooltip: '',
  helpUrl: ''
}
Blockly.Blocks['form_set_values'] = {
  init: function () {
    this.jsonInit(setValuesJson)
  }
}
Blockly.JavaScript['form_set_values'] = function (block) {
  const compVar = block.getFieldValue('Form')
  const context = getContextText(block, compVar)
  const values = Blockly.JavaScript.valueToCode(block, 'VALUE_INPUT',
    Blockly.JavaScript.ORDER_FUNCTION_CALL) || '{}'

  const code = `${context}.getComponent('${compVar}').dispatch('setValues',${values})`
  return code + '\n'
}

// ----------------表单提交  mutator----

const mixinObj = {
  mutationToDom: function () {
    var container = Blockly.utils.xml.createElement('mutation')
    container.setAttribute('success', this.successCount_)
    container.setAttribute('error', this.errorCount_)
    return container
  },
  domToMutation: function (xmlElement) {
    this.successCount_ = parseInt(xmlElement.getAttribute('success'), 10) || 0
    this.errorCount_ = parseInt(xmlElement.getAttribute('error'), 10) || 0
    this.updateShape_()
  },
  updateShape_: function () {
    if (this.successCount_) {
      const connection = this.getInput('success_func')?.connection?.targetConnection
      if (this.getInput('success_func')) {
        this.removeInput('success_func')
      }
      this.appendValueInput('success_func').setCheck('callback_function_expression')
        .appendField('提交成功回调函数')
      Blockly.Mutator.reconnect(connection, this, 'success_func')
    } else {
      if (this.getInput('success_func')) {
        this.removeInput('success_func')
      }
    }
    if (this.errorCount_) {
      const connection = this.getInput('error_func')?.connection?.targetConnection
      if (this.getInput('error_func')) {
        this.removeInput('error_func')
      }
      this.appendValueInput('error_func').setCheck('callback_function_expression')
        .appendField('提交失败回调函数')
      Blockly.Mutator.reconnect(connection, this, 'error_func')
    } else {
      if (this.getInput('error_func')) {
        this.removeInput('error_func')
      }
    }
  }
}

const helpFun = function () {
  this.successCount_ = 1
  this.errorCount_ = 1
  this.updateShape_()
}

Blockly.Extensions.registerMutator('form_submit_mutator',
  mixinObj, helpFun,
  ['success_func', 'error_func'])
